home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / eiffel / smalleif.97 / se.t / SmallEiffel / lib_std / array.e < prev    next >
Encoding:
Text File  |  1996-05-02  |  6.0 KB  |  317 lines

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. class ARRAY[E]
  5. -- 
  6. -- General purpose arrays.
  7. --
  8.  
  9. inherit COLLECTION[E];
  10.  
  11. creation {ANY}
  12.    make
  13.  
  14. feature {NONE}
  15.    
  16.    storage: POINTER;
  17.      -- Internal access to storage location.
  18.    
  19. feature
  20.    
  21.    capacity: INTEGER;
  22.      -- Internal storage capacity in number of item.
  23.    
  24.    lower: INTEGER;     
  25.      -- Lower index bound.
  26.    
  27.    upper: INTEGER;
  28.      -- Upper index bound.
  29.    
  30. feature -- Creation and Modification :
  31.    
  32.    make(minindex, maxindex: INTEGER) is
  33.      -- Make array with range [minindex .. maxindex]. 
  34.      -- When maxindex = minindex - 1, the array is empty.
  35.       require
  36.      minindex -1 <= maxindex
  37.       do
  38.      if storage /= Void then
  39.         c_inline_c("free(C->_storage);");
  40.      end;
  41.      lower := minindex;
  42.      upper := maxindex;
  43.      capacity := upper - lower + 1;
  44.      storage := Void;
  45.      if capacity > 0 then
  46.         capacity := capacity + 16;
  47.         c_inline_c("C->_storage=malloc%
  48.                %((size_t)((C->_capacity)*sizeof(*(C->_storage))));");
  49.         clear_all;
  50.      end;
  51.       ensure
  52.      lower = minindex;
  53.      upper = maxindex;
  54.      all_cleared;
  55.       end;
  56.  
  57. feature -- Modification :
  58.    
  59.    resize(minindex, maxindex: INTEGER) is
  60.      -- Resize the array. No elements will be lost in the 
  61.      -- intersection of [old lower .. old upper] and 
  62.      -- [minindex .. maxindex].
  63.      -- New positions are initialized with appropriate 
  64.      -- default values.
  65.       require
  66.      minindex <= maxindex
  67.       local
  68.      other: like Current;
  69.      i, up: INTEGER;
  70.       do
  71.      from
  72.         !!other.make(minindex,maxindex);
  73.         i := lower.max(other.lower);
  74.         up := upper.min(other.upper);
  75.      until
  76.         i > up
  77.      loop
  78.         other.put(item(i),i);
  79.         i := i + 1;
  80.      end;
  81.      if storage /= Void then
  82.         c_inline_c("free(C->_storage);");
  83.      end;
  84.      c_inline_c("memcpy(C,_other,sizeof(*C));free(_other);");
  85.       end;
  86.  
  87. feature -- No modification :
  88.  
  89.    infix "@", item (index: INTEGER): E is
  90.       do
  91.      check
  92.         storage /= Void;
  93.         capacity >= (upper - lower + 1);
  94.      end;
  95.      c_inline_c("R=(C->_storage)[a1-(C->_lower)];")
  96.       end;
  97.    
  98. feature -- Modification :
  99.    
  100.    put(element: E; index: INTEGER) is
  101.      -- Put `element' at position `index'.
  102.       do
  103.      c_inline_c("(C->_storage)[a2-(C->_lower)]=a1;");
  104.       end;
  105.  
  106.    force(element: E; index: INTEGER) is
  107.      -- Put `element' at position `index'.
  108.      -- Resize array, if `index' is not
  109.      -- inside current bounds.
  110.       do
  111.      if upper < index then
  112.         resize(lower,index);
  113.      elseif index < lower then
  114.         resize(index,upper);
  115.      end;
  116.      put(element,index);
  117.       ensure
  118.      valid_index(index); 
  119.      item(index) = element;
  120.       end;
  121.  
  122.    clear is
  123.      -- Empty the array, discard all items.
  124.       do
  125.      upper := lower - 1;
  126.       ensure
  127.      empty;
  128.       end;
  129.  
  130.    copy(other: like Current) is
  131.      -- Copy `other' onto Current.
  132.       local
  133.      i: INTEGER;
  134.       do
  135.      upper := lower - 1;
  136.      if capacity = 0 then
  137.         make(other.lower,other.upper);
  138.      else
  139.         resize(other.lower,other.upper);
  140.      end;
  141.      from
  142.         i := lower;
  143.      until
  144.         i > upper
  145.      loop
  146.         put(other.item(i),i);
  147.         i := i + 1;
  148.      end;
  149.       end;
  150.    
  151.    remove(index: INTEGER) is
  152.      -- Remove one element at position `index'. Followings 
  153.      -- elements (after `index') are moved one position left.
  154.       require
  155.      valid_index(index); 
  156.       local
  157.      i: INTEGER;
  158.       do
  159.      from  
  160.         i := index;
  161.      until
  162.         i + 1 > upper
  163.      loop
  164.         put(item(i + 1),i);
  165.         i := i + 1;
  166.      end;
  167.      upper := upper - 1;
  168.       ensure
  169.      count + 1 = old count;
  170.      upper + 1 = old upper;
  171.       end;
  172.    
  173.    remove_last is
  174.       require
  175.      not empty;
  176.       do
  177.      upper := upper - 1;
  178.       ensure
  179.      count = 1 + old count;
  180.       end;
  181.    
  182.    remove_first is
  183.       require
  184.      not empty;
  185.       do
  186.      lower := lower + 1;
  187.       ensure
  188.      count = 1 + old count;
  189.       end;
  190.    
  191. feature -- Adding Elements :
  192.    
  193.    add_last(elt: E) is
  194.       do
  195.      if capacity < count + 1 then
  196.         capacity := capacity + 16;
  197.         if capacity = 16 then
  198.            c_inline_c("C->_storage=malloc(16*sizeof(*(C->_storage)));");
  199.         else
  200.            c_inline_c("C->_storage=realloc(C->_storage,%
  201.               %((C->_capacity)*sizeof(*(C->_storage))));");
  202.         end;
  203.      end;
  204.      upper := upper + 1;
  205.      put(elt,upper);
  206.       ensure
  207.      last = elt;
  208.      count = 1 + old count
  209.       end;
  210.    
  211.    add(elt: E) is
  212.       do
  213.      if not has(elt) then
  214.         add_last(elt);
  215.      end;
  216.       ensure
  217.      has(elt);
  218.      count >= old count;
  219.       end;
  220.    
  221.    fast_add(elt: E) is
  222.       do
  223.      if not fast_has(elt) then
  224.         add_last(elt);
  225.      end;
  226.       ensure
  227.      fast_has(elt);
  228.      count >= old count;
  229.       end;
  230.    
  231.    insert(element : E; index: INTEGER) is
  232.      -- Insert `element' after position `index'.
  233.      -- Element at position `upper' will be lost!
  234.       require
  235.      inside_bounds: lower - 1 <= index and then index < upper
  236.      -- Note: Insertion is AFTER `index'!
  237.       do
  238.      if index < upper - 1 then
  239.         move(index+1,upper-1,1);
  240.      end;
  241.      put (element, index + 1);
  242.       end;
  243.    
  244.    sub_array(low, up: INTEGER): ARRAY[E] is
  245.       require
  246.      valid_index(low);
  247.      valid_index(up);
  248.      low <= up
  249.       local
  250.      i: INTEGER;
  251.       do
  252.      from  
  253.         !!Result.make(low,up);
  254.         i := low;
  255.      until
  256.         i > up
  257.      loop
  258.         Result.put(item(i),i);
  259.         i := i + 1;
  260.      end;
  261.       ensure
  262.      Result.lower = low;
  263.      Result.upper = up;
  264.       end;
  265.  
  266. feature -- Other Features :
  267.  
  268.    put_first(elt: E) is
  269.      -- Put `elt' at the first free place
  270.      -- or `add_last' it no Void places.
  271.       local
  272.      i: INTEGER;
  273.      null: E;
  274.       do
  275.      from  
  276.         i := lower;
  277.      until
  278.         i > upper or else item(i) = null
  279.      loop
  280.         i := i + 1;
  281.      end;
  282.      if i > upper then
  283.         add_last(elt);
  284.      else
  285.         put(elt,i);
  286.      end;
  287.       end;
  288.       
  289.    take_first: E is
  290.      -- Take the first element non Void or not set to 
  291.      -- the default value. Then set the corresponding 
  292.      -- place to the default value.
  293.       local
  294.      i: INTEGER;
  295.      null: E;
  296.       do
  297.      from  
  298.         i := lower;
  299.      until
  300.         i > upper or else Result /= null
  301.      loop
  302.         Result := item(i);
  303.         i := i + 1;
  304.      end;
  305.      if i <= upper then
  306.         put(null,i-1);
  307.      end;
  308.       ensure
  309.      count = old count;
  310.       end;
  311.       
  312. invariant
  313.    
  314.    capacity >= (upper - lower + 1);
  315.       
  316. end -- ARRAY[E]
  317.